home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcr / pcr4_4.lha / DIST / threads / ThreadsOrders.c < prev    next >
C/C++ Source or Header  |  1992-02-18  |  8KB  |  256 lines

  1. /* begincopyright
  2.   Copyright (c) 1988 Xerox Corporation. All rights reserved.
  3.   Use and copying of this software and preparation of derivative works based
  4.   upon this software are permitted. Any distribution of this software or
  5.   derivative works must comply with all applicable United States export
  6.   control laws. This software is made available AS IS, and Xerox Corporation
  7.   makes no warranty about the software, its performance or its conformity to
  8.   any specification. Any person obtaining a copy of this software is requested
  9.   to send their name and post office or electronic mail address to:
  10.     PCR Coordinator
  11.     Xerox PARC
  12.     3333 Coyote Hill Rd.
  13.     Palo Alto, CA
  14.   endcopyright */
  15. /*
  16.  * ThreadsOrders.c
  17.  *
  18.  * Demers, June 15, 1990 4:12:18 pm PDT
  19.  * Boehm, August 16, 1991 11:18:14 am PDT
  20.  */
  21.  
  22. #include "xr/BasicTypes.h"
  23. #include "xr/Threads.h"
  24. #include "xr/ThreadsBackdoor.h"
  25. #include "xr/ThreadsPrivate.h"
  26. #include "xr/ThreadsSignalsPrivate.h"
  27. #include "xr/ThreadsMsgPrivate.h"
  28.  
  29.  
  30. extern XR_VPE XR_NakedNotifyInner(/* XR_CV cv */);    /* ThreadsPrivate.h */
  31.  
  32.  
  33. /*
  34.  * VProcessor orders
  35.  */
  36.  
  37.  
  38. void
  39. XR_IssueVPOrder (order, proc, stop)
  40.     XR_VPOrder order;
  41.     void (*proc)(/* order */);
  42.     bool stop;
  43. {
  44.     order->vpo_proc = proc;
  45.     order->vpo_stop = stop;
  46.     if( XR_sysArea->sa_vpOrderMaster != XR_iope ) {
  47.     XR_PSem(&(XR_sysArea->sa_vpOrderSem), XR_VP_ORDER_SEM_LOCK, 1);
  48.     XR_sysArea->sa_vpOrderMaster = XR_iope;
  49.     }
  50.     XR_sysArea->sa_vpOrder = order;
  51.     XR_sysArea->sa_vpOrderNum++;
  52.     XR_RequestResched(NIL);
  53.     XR_PSem(&(XR_sysArea->sa_vpOrderSem), XR_VP_ORDER_SEM_WAIT,
  54.         XR_sysArea->sa_numVP);
  55.     if( ! stop ) {
  56.         XR_sysArea->sa_vpOrderMaster = NIL;
  57.     XR_VSem(&(XR_sysArea->sa_vpOrderSem), XR_VP_ORDER_SEM_LOCK, 1);
  58.     }
  59. }
  60.  
  61.  
  62.  
  63. /*
  64.  * IOProcessor orders
  65.  */
  66.  
  67. #define IOPODONE_INIT        FALSE
  68. #define IOPODONE_FINISHING    ((bool)(2))
  69. #define IOPODONE_DONE        ((bool)(1))
  70.  
  71. XR_Thread XR_holderOfIOPOrderLocks = NIL;
  72.  
  73. void
  74. XR_AcquireIOPOrderLocks ()
  75. {
  76.     XR_IOPE iope, iopeLim;
  77.  
  78.     iopeLim = &(XR_sysArea->sa_iope[XR_maxIOPs]);
  79.     for( iope = XR_sysArea->sa_iope; iope < iopeLim; iope++ ) {
  80.         XR_MonitorEntry( &(iope->iope_orderLock) );
  81.     }
  82.     if( XR_holderOfIOPOrderLocks != NIL )
  83.         XR_Panic("AcquireIOPOrderLocks 0");
  84.     XR_holderOfIOPOrderLocks = XR_currThread;
  85. }
  86.  
  87. void
  88. XR_ReleaseIOPOrderLocks ()
  89. {
  90.     XR_IOPE iope, iopeLim;
  91.  
  92.     if( XR_holderOfIOPOrderLocks != XR_currThread )
  93.         XR_Panic("ReleaseIOPOrderLocks 0");
  94.     XR_holderOfIOPOrderLocks = NIL;
  95.     iopeLim = &(XR_sysArea->sa_iope[XR_maxIOPs]);
  96.     for( iope = XR_sysArea->sa_iope; iope < iopeLim; iope++ ) {
  97.         XR_MonitorExit( &(iope->iope_orderLock) );
  98.     }
  99. }
  100.  
  101.  
  102. XR_IOPOResult
  103. XR_IssueIOPOrder (iop, order, proc, cancel, abortable, timeout)
  104.     XR_IOPE iop;
  105.     XR_IOPOrder order;
  106.     void (*proc)(/* order */);
  107.     void (*cancel)(/* order */);
  108.     bool abortable;
  109.     XR_Ticks timeout;
  110. {
  111.     int ans;
  112.  
  113.     XR_InitializeCondition( &(order->iopo_cv), timeout );
  114.     if( abortable ) XR_EnableAborts( &(order->iopo_cv) );
  115.     order->iopo_done = IOPODONE_INIT;
  116.     order->iopo_next = NIL;
  117.  
  118.     order->iopo_cancel = NIL;
  119.     order->iopo_proc = proc;
  120.     if( XR_holderOfIOPOrderLocks != XR_currThread )
  121.         XR_MonitorEntry( &(iop->iope_orderLock) );
  122.     XR_ASSERT( (iop->iope_order == NIL), "IssueIOPOrder a0" );
  123.     iop->iope_order = order;
  124.     if( kill(iop->iope_pid, XR_SIG_RESCHED) < 0 ) {
  125.         XR_ConsoleMsg("%? kill(pid:%d,sig:%d) failed err %d\n",
  126.                 iop->iope_pid, XR_SIG_RESCHED, XR_GetErrno() );
  127.         XR_Panic("IssueIOPOrder 0");
  128.     }
  129.     (void) XR_WaitCV( &(iop->iope_orderAccepted), NIL );
  130.     if( XR_holderOfIOPOrderLocks != XR_currThread )
  131.         XR_MonitorExit( &(iop->iope_orderLock) );
  132.  
  133.     ans = XR_WaitCV( &(order->iopo_cv), NIL );
  134.     if( ans == 0 ) {
  135.         if( order->iopo_done != IOPODONE_INIT ) {
  136.             while( order->iopo_done != IOPODONE_DONE ) {
  137.                 XR_SpinStep(1000);
  138.             }
  139.             return XR_IOPO_RESULT_OK;
  140.         }
  141.     }
  142.     /*
  143.      * order failed, cancel it ...
  144.      */
  145.     if( cancel != NIL ) {
  146.         order->iopo_cancel = cancel;
  147.         if( XR_holderOfIOPOrderLocks != XR_currThread )
  148.         XR_MonitorEntry( &(iop->iope_orderLock) );
  149.     XR_ASSERT( (iop->iope_order == NIL), "IssueIOPOrder a1" );
  150.     iop->iope_order = order;
  151.     if( kill(iop->iope_pid, XR_SIG_RESCHED) < 0 )
  152.         XR_Panic("IssueIOPOrder 1");
  153.     (void) XR_WaitCV( &(iop->iope_orderAccepted), NIL );
  154.     if( XR_holderOfIOPOrderLocks != XR_currThread )
  155.         XR_MonitorExit( &(iop->iope_orderLock) );
  156.     }
  157.     return( (ans != 0) ? XR_IOPO_RESULT_ABORTED : XR_IOPO_RESULT_TIMEDOUT );
  158. }
  159.  
  160.  
  161. XR_IOPOResult
  162. XR_IssueIOPOrders (order, remoteProc, localProc)
  163.     XR_IOPOrder order;
  164.     void (*remoteProc)(/* order */);
  165.     void (*localProc)(/* order, iope */);
  166. {
  167.     int ans,i;
  168.     XR_IOPE iope, iopeLim;
  169.     XR_IOPOrder iopo;
  170.     struct XR_IOPOrderRep iopor[XR_MAX_IOPS];
  171.  
  172.     iopeLim = &(XR_sysArea->sa_iope[XR_maxIOPs]);
  173.  
  174.     /* initialize ioporder structures */
  175.         /* InitializeCondition( &(order->iopo_cv), ... ); (individually!) */
  176.         order->iopo_done = IOPODONE_INIT;
  177.         order->iopo_next = NIL;
  178.         order->iopo_cancel = NIL;
  179.         order->iopo_proc = remoteProc;
  180.         (void) bzero( ((char *)(order->iopo_results)),
  181.                 (sizeof order->iopo_results) );
  182.         for( i = 0; i < XR_maxIOPs; i++ ) {
  183.             iopo = &(iopor[i]);
  184.             (void) bcopy( ((char *)(order)), ((char *)(iopo)),
  185.                     sizeof(struct XR_IOPOrderRep) );
  186.             XR_InitializeCondition( &(iopo->iopo_cv), XR_WAIT_FOREVER );
  187.         }
  188.     /* acquire all iop order locks */
  189.         if( XR_holderOfIOPOrderLocks != XR_currThread ) {
  190.             for( iope = XR_sysArea->sa_iope; iope < iopeLim; iope++ ) {
  191.                 XR_MonitorEntry( &(iope->iope_orderLock) );
  192.             }
  193.         }
  194.     /* issue order to each iop */
  195.         for( i = 0; i < XR_maxIOPs; i++ ) {
  196.             iope = &(XR_sysArea->sa_iope[i]);
  197.             iopo = &(iopor[i]);
  198.             XR_ASSERT( (iope->iope_order == NIL), "IssueIOPOrders a0" );
  199.             if( localProc != NIL ) (*localProc)(iopo, iope);
  200.             iope->iope_order = iopo;
  201.             if( kill(iope->iope_pid, XR_SIG_RESCHED) < 0 )
  202.                 XR_Panic("IssueIOPOrders 0");
  203.         }
  204.  
  205.     /* wait for orders to be accepted by all iops */
  206.         for( iope = XR_sysArea->sa_iope; iope < iopeLim; iope++ ) {
  207.             ans = XR_WaitCV( &(iope->iope_orderAccepted), NIL );
  208.             if( ans != 0 ) XR_Panic("IssueIOPOrders 1a");
  209.         }
  210.      /* release all iop order locks */
  211.         if( XR_holderOfIOPOrderLocks != XR_currThread ) {
  212.             for( iope = XR_sysArea->sa_iope; iope < iopeLim; iope++ ) {
  213.                 XR_MonitorExit( &(iope->iope_orderLock) );
  214.             }
  215.         }
  216.     /* wait for orders to be executed by all iops */
  217.         for( i = 0; i < XR_maxIOPs; i++ ) {
  218.             iope = &(XR_sysArea->sa_iope[i]);
  219.             iopo = &(iopor[i]);
  220.             ans = XR_WaitCV( &(iopo->iopo_cv), NIL );
  221.             if( (ans == 0) && (iopo->iopo_done != IOPODONE_INIT) ) {
  222.                 int prevRes, res;
  223.                 while( iopo->iopo_done != IOPODONE_DONE ) {
  224.                     XR_SpinStep(1000);
  225.                 }
  226.                 prevRes = (int)(order->iopo_results[0]);
  227.                 res = (int)(iopo->iopo_results[0]);
  228.                 if( (prevRes == 0) || (res < 0) ) {
  229.                     (void) bcopy( ((char *)(iopo->iopo_results)),
  230.                             ((char *)(order->iopo_results)),
  231.                             (sizeof order->iopo_results) );
  232.                 }
  233.             } else {
  234.                 XR_Panic("IssueIOPOrders 1b");
  235.             }
  236.         }
  237.     return XR_IOPO_RESULT_OK;
  238. }
  239.  
  240.  
  241.  
  242. void
  243. XR_NotifyIOPODone(iopo)
  244.     XR_IOPOrder iopo;
  245. {
  246.     XR_VPE vpe;
  247.  
  248.     XR_ASSERT((!(iopo->iopo_done)), "NotifyIOPODone a0");
  249.     XR_ASSERT((!(iopo->iopo_cv.cv_wakeupWaiting)), "NotifyIOPODone a1");
  250.     iopo->iopo_done = IOPODONE_FINISHING;
  251.     vpe = XR_NakedNotifyInner( &(iopo->iopo_cv) );
  252.     iopo->iopo_done = IOPODONE_DONE;
  253.     if( vpe != NIL ) XR_RequestResched(vpe);
  254. }
  255.  
  256.